package thread.n8;

import java.util.Arrays;
import java.util.Random;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * CountdownLatch的测试类。
 */
public class CountdownLatchTest {

    /**
     * CountdownLatch与线程池的使用：
     *      注意：如果在线程池中，所有的线程都执行了【await】方法，
     *      没有空闲线程执行。【countDown】方法，那么就会导致，这个线程池死锁。
     * @param args
     * @throws InterruptedException
     */
    public static void main1(String[] args) throws InterruptedException {
        CountDownLatch latch = new CountDownLatch(3);
        //如果线程池的线程数量只有一个。
        ExecutorService service = Executors.newFixedThreadPool(1);

        //并且第一次执行的还是【await】阻塞方法，那么后续的【countDown】方法在也没有机会执行了。
        service.submit(()->{
            try {
                System.out.println("waiting...");
                latch.await();
                System.out.println("wait end...");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });

        Thread.sleep(100);

        service.submit(() -> {
            System.out.println("begin...");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            latch.countDown();
            System.out.println("end..."+latch.getCount());
        });

        service.submit(() -> {
            System.out.println("begin...");
            try {
                Thread.sleep(1500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            latch.countDown();
            System.out.println("end..."+latch.getCount());
        });

        service.submit(() -> {
            System.out.println("begin...");
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            latch.countDown();
            System.out.println("end..."+latch.getCount());
        });

    }


    /**
     * 应用：等待多线程准备完毕。
     * @param args
     * @throws InterruptedException
     */
    public static void main(String[] args) throws InterruptedException {
        AtomicInteger num = new AtomicInteger(0);

        ExecutorService service = Executors.newFixedThreadPool(10, (r) -> {
            return new Thread(r, "t" + num.getAndIncrement());
        });

        CountDownLatch latch = new CountDownLatch(10);

        String[] all = new String[10];
        Random r = new Random();
        for (int j = 0; j < 10; j++) {
            int x = j;
            service.submit(() -> {
                for (int i = 0; i <= 100; i++) {
                    try {
                        Thread.sleep(r.nextInt(100));
                    } catch (InterruptedException e) {
                    }
                    all[x] = Thread.currentThread().getName() + "(" + (i + "%") + ")";
                    System.out.print("\r" + Arrays.toString(all));
                }
                latch.countDown();
            });
        }

        latch.await();
        System.out.println("\n游戏开始...");
        service.shutdown();
    }
}
